package com.self.cartoon.selfcartoon.config.webSocket;

import com.alibaba.fastjson2.JSONObject;
import com.self.cartoon.selfcartoon.service.impl.ImgServiceImpl;
import com.self.cartoon.selfcartoon.vo.imgVo;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class MyWebSocketHandler extends TextWebSocketHandler {

    //加载到第几行
    public static ThreadLocal<Integer> index = new ThreadLocal<>();

    //已加载img
    public static ThreadLocal<Map<String,Boolean>> loadedImg = new ThreadLocal<>();
    //已消费
    public static ThreadLocal<Map<String,Boolean>> consumedImg = new ThreadLocal<>();

    //同步锁
    public static Map<String,Object> lockMap = new ConcurrentHashMap<>();

    // img数据 base64形式
    public static ThreadLocal<List<imgVo>> imgData = new ThreadLocal<>();

    private ImgServiceImpl imgService = new ImgServiceImpl();

    public static void addImgData(imgVo vo) {
        List<imgVo> imgVos = imgData.get();
        if(CollectionUtils.isEmpty(imgVos)){
            imgVos = new ArrayList<>();
            imgData.set(imgVos);
        }
        imgVos.add(vo);
    }

    public static boolean existsUrl(String url){
        Map<String, Boolean> map = loadedImg.get();
        if(map.containsKey(url)){
            return true;
        }
        map.put(url,true);
        return false;
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String receivedMsg = message.getPayload();
        System.out.println("Received: " + receivedMsg);
        // 这里可以处理接收到的消息，并发送响应给客户端
        try {
            JSONObject jsonObject = JSONObject.parseObject(receivedMsg);
            String name = jsonObject.getString("name");
            if(name == null){
                return;
            }
            String id = session.getId();
            Object lock = lockMap.get(id);
            if("getNewData".equals(name)){
                //获取新数据
                synchronized (lock){
                    lock.notify();
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        // session.sendMessage(new TextMessage("Server received: " + receivedMsg));
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("Connection established");
        // 可以在这里执行连接建立后的操作
        String id = session.getId();

        initThreadLocalData(id);

        imgService.getImgBaseData(id,"https://www.kanman.com/91961/1007.html");

        Object lock = lockMap.get(id);
        synchronized (lock){
            while(true){
                List<imgVo> imgVos = imgData.get();
                Integer start = index.get();
                Map<String, Boolean> consumed = consumedImg.get();
                for (; start < imgVos.size(); start++) {
                    imgVo vo = imgVos.get(start);
                    String url = vo.getUrl();
                    if(consumed.containsKey(url)){
                        continue;
                    }
                    session.sendMessage(new TextMessage(vo.getData()));
                    consumed.put(url,true);
                }
                index.set(start);
                lock.wait();
            }
        }
    }

    private static void initThreadLocalData(String id) {
        lockMap.put(id, new Object());

        loadedImg.set(new ConcurrentHashMap<>());

        index.set(0);

        consumedImg.set(new ConcurrentHashMap<>());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.out.println("Connection closed with status: " + status);
        // 连接关闭时的操作
        index.remove();
        loadedImg.remove();
        lockMap.remove(session.getId());
        imgData.remove();
    }
}
